SPB Git forge
3commits 1branches 0releases
417.0 KBsize
maindefault branch
10 days agolast push
TypeScript 66.5% Python 30.9% JavaScript 1.4% CSS 0.7%
2.9 KB · 56 lines tsx
Raw Blame History
1import { ImageResponse } from 'next/og';2import { api, safe } from '@/lib/api';3import { fmtInt } from '@/lib/format';45export const alt = 'Constellation summary — SatelliteIndex';6export const size = { width: 1200, height: 630 };7export const contentType = 'image/png';89const ORBIT_HEX: Record<string, string> = { LEO: '#38d3ff', MEO: '#8f7dff', GEO: '#f5b544', HEO: '#ff7ab6' };1011export default async function Image({ params }: { params: Promise<{ slug: string }> }) {12  const { slug } = await params;13  const res = await safe(api.constellation(slug));14  const d = res?.data ?? null;15  const orbit = d?.orbit_class ?? 'MIXED';16  const color = ORBIT_HEX[orbit] ?? '#7c869e';1718  return new ImageResponse(19    (20      <div style={{ width: '100%', height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', padding: 64, background: 'linear-gradient(135deg, #060912 0%, #0b1020 60%, #111830 100%)', color: '#eaf0ff', fontFamily: 'sans-serif' }}>21        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>22          <div style={{ display: 'flex', alignItems: 'center', gap: 14, fontSize: 26, letterSpacing: 4, textTransform: 'uppercase', color: '#a3aec8' }}>23            <div style={{ width: 14, height: 14, borderRadius: 999, background: '#38d3ff' }} />24            <div>SatelliteIndex · Constellation</div>25          </div>26          <div style={{ display: 'flex', padding: '8px 18px', borderRadius: 8, border: `2px solid ${color}`, color, fontSize: 28, fontWeight: 700 }}>{orbit}</div>27        </div>2829        {d ? (30          <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>31            <div style={{ fontSize: d.name.length > 28 ? 60 : 84, fontWeight: 700, letterSpacing: -2, lineHeight: 1 }}>{d.name}</div>32            <div style={{ fontSize: 34, color: '#a3aec8' }}>{`${d.operator_name ?? 'Operator unavailable'}${d.country_name ? ` · ${d.country_name}` : ''}`}</div>33          </div>34        ) : (35          <div style={{ fontSize: 72, fontWeight: 700 }}>Constellation</div>36        )}3738        <div style={{ display: 'flex', gap: 56, borderTop: '1px solid rgba(160,180,230,0.28)', paddingTop: 28 }}>39          {[40            { label: 'Active satellites', value: d ? fmtInt(d.active) : '—', c: '#38d17f' },41            { label: 'Total launched', value: d ? fmtInt(d.total) : '—', c: '#eaf0ff' },42            { label: 'Launched 365 d', value: d ? fmtInt(d.launched_last_365d) : '—', c: '#eaf0ff' },43            { label: 'Launches', value: d ? fmtInt(d.launches) : '—', c: '#eaf0ff' },44          ].map((k) => (45            <div key={k.label} style={{ display: 'flex', flexDirection: 'column' }}>46              <div style={{ fontSize: 20, letterSpacing: 3, textTransform: 'uppercase', color: '#6b7694' }}>{k.label}</div>47              <div style={{ fontSize: 56, fontWeight: 700, color: k.c, marginTop: 6 }}>{k.value}</div>48            </div>49          ))}50        </div>51      </div>52    ),53    size,54  );55}56